home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / borcmpad / mpprint.c < prev    next >
C/C++ Source or Header  |  1991-07-23  |  12KB  |  403 lines

  1. /***************************************************************************
  2.  *                                       *
  3.  *  MODULE    : MpPrint()                           *
  4.  *                                       *
  5.  *  PURPOSE    : Printing code for MultiPad.                   *
  6.  *                                       *
  7.  *  FUNCTIONS    : GetPrinterDC ()       -  Creates a printer DC for the *
  8.  *                          default device.           *
  9.  *                                       *
  10.  *          AbortProc ()           -  Export proc. for GDI to check*
  11.  *                          print abort.           *
  12.  *                                       *
  13.  *          PrintDlgProc ()       -  Dialog function for the print*
  14.  *                          cancel dialog.           *
  15.  *                                       *
  16.  *          PrintFile ()           -  Prints the contents of the   *
  17.  *                          edit control.           *
  18.  *                                       *
  19.  *          GetInitializationData () -  Gets DC initialisation data  *
  20.  *                          from a DC supporting       *
  21.  *                          ExtDeviceMode().           *
  22.  *                                       *
  23.  ***************************************************************************/
  24. #include "multipad.h"
  25.  
  26. BOOL fAbort;        /* TRUE if the user has aborted the print job     */
  27. HWND hwndPDlg;        /* Handle to the cancel print dialog         */
  28. char szDevice[160];    /* Contains the device, the driver, and the port */
  29. PSTR szDriver;        /* Pointer to the driver name             */
  30. PSTR szPort;        /* Port, ie, LPT1                 */
  31. PSTR szTitle;        /* Global pointer to job title             */
  32. int iPrinter = 0;    /* level of available printer support.         */
  33.             /* 0 - no printer available             */
  34.             /* 1 - printer available             */
  35.             /* 2 - driver supports 3.0 device initialization */
  36. HANDLE hInitData=NULL;    /* handle to initialization data         */
  37.  
  38. char szExtDeviceMode[] = "EXTDEVICEMODE";
  39.  
  40. /****************************************************************************
  41.  *                                        *
  42.  *  FUNCTION   : GetPrinterDC ()                        *
  43.  *                                        *
  44.  *  PURPOSE    : Creates a printer display context for the default device.  *
  45.  *         As a side effect, it sets the szDevice and szPort variables*
  46.  *         It also sets iPrinter to the supported level of printing.  *
  47.  *                                        *
  48.  *  RETURNS    : HDC   - A handle to printer DC.                *
  49.  *                                        *
  50.  ****************************************************************************/
  51. HDC FAR PASCAL GetPrinterDC (void)
  52. {
  53.     HDC      hdc;
  54.     LPSTR    lpdevmode = NULL;
  55.  
  56.     iPrinter = 0;
  57.  
  58.     /* Get the printer information from win.ini into a buffer and
  59.      * null terminate it.
  60.      */
  61.     GetProfileString ( "windows", "device", "" ,szDevice, sizeof(szDevice));
  62.     for (szDriver = szDevice; *szDriver && *szDriver != ','; szDriver++)
  63.     ;
  64.     if (*szDriver)
  65.     *szDriver++ = 0;
  66.  
  67.     /* From the current position in the buffer, null teminate the
  68.      * list of ports
  69.      */
  70.     for (szPort = szDriver; *szPort && *szPort != ','; szPort++)
  71.     ;
  72.     if (*szPort)
  73.     *szPort++ = 0;
  74.  
  75.     /* if the device, driver and port buffers all contain meaningful data,
  76.      * proceed.
  77.      */
  78.     if (!*szDevice || !*szDriver || !*szPort){
  79.     *szDevice = 0;
  80.     return NULL;
  81.     }
  82.  
  83.     /* Create the printer display context */
  84.     if (hInitData){
  85.     /* Get a pointer to the initialization data */
  86.     lpdevmode = (LPSTR) LocalLock (hInitData);
  87.  
  88.     if (lstrcmp(szDevice, lpdevmode)){
  89.         /* User has changed the device... cancel this setup, as it is
  90.          * invalid (although if we worked harder we could retain some
  91.          * of it).
  92.          */
  93.         lpdevmode = NULL;
  94.         LocalUnlock (hInitData);
  95.         LocalFree (hInitData);
  96.         hInitData = NULL;
  97.     }
  98.     }
  99.     hdc = CreateDC (szDriver, szDevice, szPort, lpdevmode);
  100.  
  101.     /* Unlock initialization data */
  102.     if (hInitData)
  103.     LocalUnlock (hInitData);
  104.  
  105.     if (!hdc)
  106.     return NULL;
  107.  
  108.  
  109.     iPrinter = 1;
  110.  
  111.     /* Find out if ExtDeviceMode() is supported and set flag appropriately */
  112.     if (GetProcAddress(GetModuleHandle (szDriver), szExtDeviceMode))
  113.     iPrinter = 2;
  114.  
  115.     return hdc;
  116.  
  117. }
  118.  
  119. /****************************************************************************
  120.  *                                        *
  121.  *  FUNCTION   : AbortProc()                            *
  122.  *                                        *
  123.  *  PURPOSE    : To be called by GDI print code to check for user abort.    *
  124.  *                                        *
  125.  ****************************************************************************/
  126. int FAR PASCAL AbortProc ( hdc, reserved )
  127. HDC hdc;
  128. WORD reserved;
  129. {
  130.     MSG msg;
  131.  
  132.     /* Allow other apps to run, or get abort messages */
  133.     while (!fAbort && PeekMessage (&msg, NULL, NULL, NULL, TRUE))
  134.     if (!hwndPDlg || !IsDialogMessage(hwndPDlg, &msg)){
  135.         TranslateMessage (&msg);
  136.         DispatchMessage  (&msg);
  137.     }
  138.     return !fAbort;
  139. }
  140.  
  141. /****************************************************************************
  142.  *                                        *
  143.  *  FUNCTION   : PrintDlgProc ()                        *
  144.  *                                        *
  145.  *  PURPOSE    : Dialog function for the print cancel dialog box.        *
  146.  *                                        *
  147.  *  RETURNS    : TRUE  - OK to abort/ not OK to abort                *
  148.  *         FALSE - otherwise.                        *
  149.  *                                        *
  150.  ****************************************************************************/
  151. BOOL FAR PASCAL PrintDlgProc(HWND hwnd, WORD msg, WORD wParam, LONG lParam)
  152. {
  153.     switch (msg){
  154.     case WM_INITDIALOG:
  155.         /* Set up information in dialog box */
  156.         SetDlgItemText (hwnd, IDD_PRINTDEVICE, (LPSTR)szDevice);
  157.         SetDlgItemText (hwnd, IDD_PRINTPORT, (LPSTR)szPort);
  158.         SetDlgItemText (hwnd, IDD_PRINTTITLE, (LPSTR)szTitle);
  159.         break;
  160.  
  161.     case WM_COMMAND:
  162.         /* abort printing if the only button gets hit */
  163.         fAbort = TRUE;
  164.         break;
  165.  
  166.     default:
  167.         return FALSE;
  168.     }
  169.     return TRUE;
  170. }
  171.  
  172. /****************************************************************************
  173.  *                                        *
  174.  *  FUNCTION   : PrintFile ()                            *
  175.  *                                        *
  176.  *  PURPOSE    : Prints the contents of the edit control.            *
  177.  *                                        *
  178.  ****************************************************************************/
  179.  
  180. VOID FAR PASCAL PrintFile(HWND hwnd)
  181. {
  182.     HDC     hdc;
  183.     int     yExtPage;
  184.     char    sz[32];
  185.     WORD    cch;
  186.     WORD    ich;
  187.     PSTR    pch;
  188.     WORD    iLine;
  189.     WORD    nLinesEc;
  190.     HANDLE  hT;
  191.     FARPROC lpfnAbort;
  192.     FARPROC lpfnPDlg;
  193.     HWND    hwndPDlg;
  194.     WORD    dy;
  195.     int     yExtSoFar;
  196.     WORD    fError = TRUE;
  197.     HWND    hwndEdit;
  198.  
  199.     hwndEdit = (HWND)GetWindowWord(hwnd,GWW_HWNDEDIT);
  200.  
  201.     /* Create the job title by loading the title string from STRINGTABLE */
  202.     cch = LoadString (hInst, IDS_PRINTJOB, sz, sizeof(sz));
  203.     szTitle = sz + cch;
  204.     cch += GetWindowText (hwnd, sz + cch, 32 - cch);
  205.     sz[31] = 0;
  206.  
  207.     /* Make instances of the Abort proc. and the Print dialog function */
  208.     lpfnAbort = MakeProcInstance (AbortProc, hInst);
  209.     if (!lpfnAbort)
  210.     goto getout;
  211.     lpfnPDlg = MakeProcInstance (PrintDlgProc, hInst);
  212.     if (!lpfnPDlg)
  213.     goto getout4;
  214.  
  215.     /* Initialize the printer */
  216.     hdc = GetPrinterDC();
  217.     if (!hdc)
  218.     goto getout5;
  219.  
  220.     /* Disable the main application window and create the Cancel dialog */
  221.     EnableWindow (hwndFrame, FALSE);
  222.     hwndPDlg = CreateDialog (hInst, IDD_PRINT, hwnd, lpfnPDlg);
  223.     if (!hwndPDlg)
  224.     goto getout3;
  225.     ShowWindow (hwndPDlg, SW_SHOW);
  226.     UpdateWindow (hwndPDlg);
  227.  
  228.     /* Allow the app. to inform GDI of the escape function to call */
  229.     if (Escape(hdc, SETABORTPROC, 0, (LPSTR)lpfnAbort, NULL) < 0)
  230.     goto getout1;
  231.  
  232.     /* Initialize the document */
  233.     if (Escape(hdc, STARTDOC, cch, (LPSTR)sz, NULL) < 0)
  234.     goto getout1;
  235.  
  236.     /* Get the height of one line and the height of a page */
  237.     dy = HIWORD (GetTextExtent (hdc, "CC", 2));
  238.     yExtPage = GetDeviceCaps (hdc, VERTRES);
  239.  
  240.     /* Get the lines in document and and a handle to the text buffer */
  241.     iLine     = 0;
  242.     yExtSoFar = 0;
  243.     nLinesEc  = (WORD)SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L);
  244.     hT          = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  245.  
  246.     /* While more lines print out the text */
  247.     while (iLine < nLinesEc){
  248.     if (yExtSoFar + dy > yExtPage){
  249.         /* Reached the end of a page. Tell the device driver to eject a
  250.          * page
  251.          */
  252.         if (Escape(hdc, NEWFRAME, 0, NULL, NULL) < 0 || fAbort)
  253.         goto getout2;
  254.         yExtSoFar = 0;
  255.     }
  256.  
  257.     /* Get the length and position of the line in the buffer
  258.      * and lock from that offset into the buffer */
  259.     ich = (WORD)SendMessage (hwndEdit, EM_LINEINDEX, iLine, 0L);
  260.     cch = (WORD)SendMessage (hwndEdit, EM_LINELENGTH, ich, 0L);
  261.     pch = LocalLock(hT) + ich;
  262.  
  263.     /* Print the line and unlock the text handle */
  264.     TextOut (hdc, 0, yExtSoFar, (LPSTR)pch, cch);
  265.     LocalUnlock (hT);
  266.  
  267.     /* Test and see if the Abort flag has been set. If yes, exit. */
  268.     if (fAbort)
  269.         goto getout2;
  270.  
  271.     /* Move down the page */
  272.     yExtSoFar += dy;
  273.     iLine++;
  274.     }
  275.  
  276.     /* Eject the last page. */
  277.     if (Escape(hdc, NEWFRAME, 0, NULL, NULL) < 0)
  278.     goto getout2;
  279.  
  280.     /* Complete the document. */
  281.     if (Escape(hdc, ENDDOC, 0, NULL, NULL) < 0){
  282. getout2:
  283.     /* Ran into a problem before NEWFRAME? Abort the document */
  284.     Escape( hdc, ABORTDOC, 0, NULL, NULL);
  285.     }
  286.     else
  287.     fError=FALSE;
  288.  
  289. getout3:
  290.     /* Close the cancel dialog and re-enable main app. window */
  291.     EnableWindow (hwndFrame, TRUE);
  292.     DestroyWindow (hwndPDlg);
  293.  
  294. getout1:
  295.     DeleteDC(hdc);
  296.  
  297. getout5:
  298.     /* Get rid of dialog procedure instances */
  299.     FreeProcInstance (lpfnPDlg);
  300.  
  301. getout4:
  302.     FreeProcInstance (lpfnAbort);
  303.  
  304. getout:
  305.  
  306.     /* Error? make sure the user knows... */
  307.     if (fError)
  308.     MPError (hwnd, MB_OK | MB_ICONEXCLAMATION, IDS_PRINTERROR, (LPSTR)szTitle);
  309.  
  310.     return;
  311. }
  312.  
  313. /****************************************************************************
  314.  *                                        *
  315.  *  FUNCTION   : GetInitializationData()                    *
  316.  *                                        *
  317.  *  PURPOSE    : Gets DC initialization data from a printer driver        *
  318.  *         supporting ExtDeviceMode(). Called in response to the        *
  319.  *         File/Printer setup menu selection.                *
  320.  *                                        *
  321.  *         This function allows the user to change the printer        *
  322.  *         settings FOR MULTIPAD ONLY.  This allows Multipad to print *
  323.  *         in a variety of settings without messing up any other        *
  324.  *         applications. In a more sophisticated application, this    *
  325.  *         setup could even be saved on a document-by-document basis. *
  326.  *                                        *
  327.  ****************************************************************************/
  328. BOOL FAR PASCAL GetInitializationData( hwnd )
  329. HWND hwnd ;
  330. {
  331.     LPSTR     lpOld;
  332.     LPSTR     lpNew;
  333.     FARPROC   lpfn;
  334.     HANDLE    hT,hDrv;
  335.     char      sz[32];
  336.     WORD      cb;
  337.     int       flag;
  338.  
  339.     /* Pop up dialog for user and retain data in app buffer */
  340.     flag = DM_PROMPT | DM_COPY;
  341.  
  342.     /* Load the device driver and find the ExtDeviceMode() function */
  343.     wsprintf (sz, "%s.drv", (LPSTR)szDriver);
  344.     if ((hDrv = LoadLibrary (sz)) < 32)
  345.     return FALSE;
  346.     if (!(lpfn = GetProcAddress (hDrv, szExtDeviceMode)))
  347.     return FALSE;
  348.  
  349.     if (hInitData){
  350.     /* We have some old data... we want to modify the previously specified
  351.      * setup rather than starting with the default setup.
  352.      */
  353.     lpOld = (LPSTR)LocalLock(hInitData);
  354.     flag |= DM_MODIFY;
  355.     }
  356.     else
  357.     lpOld = NULL;
  358.  
  359.     /* Get the number of bytes needed for the init data */
  360.     cb = (*lpfn) (hwnd,
  361.           hDrv,
  362.           NULL,
  363.           (LPSTR)szDevice,
  364.           (LPSTR)szPort,
  365.           (LPDEVMODE)NULL,
  366.           (LPSTR)NULL,
  367.           0);
  368.  
  369.     /* Grab some memory for the new data and lock it. */
  370.     hT      = LocalAlloc (LHND,cb);
  371.     lpNew = (LPSTR)LocalLock (hT);
  372.  
  373.     /* Post the device mode dialog. 0 flag iff user hits OK button */
  374.     if ((*lpfn) (hwnd,
  375.          hDrv,
  376.          (LPDEVMODE)lpNew,
  377.          (LPSTR)szDevice,
  378.          (LPSTR)szPort,
  379.          (LPDEVMODE)lpOld,
  380.          (LPSTR)NULL,
  381.          flag)==IDOK)
  382.     flag = 0;
  383.  
  384.     /* Unlock the input structures */
  385.     LocalUnlock (hT);
  386.     if (hInitData)
  387.     LocalUnlock (hInitData);
  388.  
  389.     /* If the user hit OK and everything worked, free the original init.
  390.      * data and retain the new one.  Otherwise, toss the new buffer.
  391.      */
  392.     if (flag)
  393.     LocalFree (hT);
  394.     else{
  395.     if (hInitData)
  396.         LocalFree (hInitData);
  397.     hInitData = hT;
  398.     }
  399.  
  400.     FreeLibrary(hDrv);
  401.     return (!flag);
  402. }
  403.